/*
 * TOSEExplorer.cpp
 *
 * This file is a part of TermOSEmulator.
 *
 * Written by Peter Winchester <wincsoft_pw@outlook.com>
 * Copyright (C) 2021 Peter Winchester.
 *
 * TermOSEmulator is free software, follows the GNU General
 * Public License.
 *
 * NOTE: TermOSEmulator requires Windows API, so it can only
 * run on the Windows.
 *
 */

#include "TOSEExplorer.h"

Directory *dirRoot, *dirCrt;
vector<string> pathCrt;
ofstream fout;

TOSEFile::TOSEFile()
{
    name.clear();
    type.clear();
}

Directory::Directory()
{
    dirFather = NULL;
    name.clear();
    dirChild.clear();
    file.clear();
};

//建立一个新目录
int createNewDir(string argName)
{
    if (argName == "") return 0; //目录名非法

    /* 避免两个目录同名 */
    for (int i = 0; i < dirCrt->dirChild.size(); i++)
    {
        if (dirCrt->dirChild[i]->name == argName)
        {
            printf("Cannot create the directory, because there is already a directory with the save name.\n");
            return 0;
        }
    }

    /* 避免一些不明错误 */
    try
    {
        Directory *tmp = new Directory;
        /* 初始化新目录的基本信息 */
        tmp->name = argName;
        tmp->dirFather = dirCrt;
        dirCrt->dirChild.push_back(tmp);

        /* 在 Windows 上建立目录 */
        char dir[MAX_STRING_LEN];
        memset(dir, 0, sizeof(dir));
        strcat(dir, systemRootPath);
        for (int i = 1; i < pathCrt.size(); i++)
        {
            for (int j = 0; j < pathCrt[i].length(); j++) dir[strlen(dir)] = pathCrt[i][j];
            dir[strlen(dir)] = '/';
        }
        for (int i = 0; i < argName.length(); i++) dir[strlen(dir)] = argName[i];
        if (CreateDirectoryA((LPCSTR)dir, NULL)) updateExplorer();
    }
    catch (...)
    {
        printf("Failed! Unknown error.\n");
        return 0;
    }
    return 1;
}

//创建一个新文件
int createNewFile(string argName, string argType)
{
    if (argName == "" | argType == "") return 0; //文件名错误
    try //避免一些不明错误
    {
        TOSEFile tmp;
        /* 初始化文件信息 */
        tmp.name = argName, tmp.type = argType;
        dirCrt->file.push_back(tmp);
    }
    catch (...)
	{
		return 0;
	}
    return 1;
}

//删除文件
int removeFile(string argName, string argType)
{
    if (argName == "" | argType == "") return 0; //参数非法
    /* 查找文件 */
    for (int i = 0; i < dirCrt->file.size(); i++)
    {
        if (dirCrt->file[i].name == argName & dirCrt->file[i].type == argType)
        {
            /* 删除该文件 */
            for (int j = i; j < dirCrt->file.size() - 1; j++)
                dirCrt->file[j] = dirCrt->file[j + 1];
            dirCrt->file.pop_back();
            updateExplorer();
            return 1;
        }
    }
    return 0; //文件未找到
}

//改变当前目录
int goToDir(string argName)
{
    if (argName == "") return 0; //参数不合法
    if (argName == "..") //目标目录是父级目录
    {
        if (dirCrt == dirRoot) return 0; //若当前目录为根目录，则不存在父级目录
        dirCrt = dirCrt->dirFather;
        pathCrt.pop_back();
        return 1;
    }
    for (int i = 0; i < dirCrt->dirChild.size(); i++) //查找目标目录
    {
        if (dirCrt->dirChild[i]->name == argName)
        {
            dirCrt = dirCrt->dirChild[i];
            pathCrt.push_back(argName);
            return 1;
        }
    }
    return 0;
}

//删除一个目录
int delDir(string dirPath)
{
    /* 通过执行一个 cmd 命令来删除目录 */
    char cmd[MAX_STRING_LEN];
    memset(cmd, 0, sizeof(cmd));
    sprintf(cmd, "rmdir /s /q \"%s\"", dirPath.c_str());
    int res = system(cmd);
    if (res == 0) return 1;
    return 0;
}

//更新资源管理器
void updateExplorer()
{
    fout.open("../dat/explorerdat.txt", ios::out);
    writeExplorerData(dirRoot);
    fout.close();
}

//更新资源管理器数据文件
void writeExplorerData(Directory *argDir)
{
    /* 记录当前目录下的文件 */
    for (int i = 0; i < argDir->file.size(); i++)
        fout << "mf " << argDir->file[i].name << " " << argDir->file[i].type << endl;
    /* 记录当前目录下的子目录 */
    for (int i = 0; i < argDir->dirChild.size(); i++)
    {
        fout << "md " << argDir->dirChild[i]->name << endl;
        fout << "cd " << argDir->dirChild[i]->name << endl;
        writeExplorerData(argDir->dirChild[i]);
        fout << "cd .." << endl;
    }
}

//初始化资源管理器
int initExplorer()
{
    /* 创建根目录 */
    dirRoot = new Directory;
    dirRoot->name = "root";
    dirCrt = dirRoot;
    pathCrt.push_back("root");

    /* 检查资源管理器数据文件 */
    string opt;
    FILE *test = fopen("../dat/explorerdat.txt", "r");
    if (test == NULL) return 0;
    fclose(test);

    /* 读取资源管理器数据 */
    ifstream fin("../dat/explorerdat.txt");
    while (fin >> opt)
    {
        if (opt == "md") //创建一个子目录
        {
            string name;
            fin >> name;
            if (!createNewDir(name))
            {
                fin.close();
                return 0;
            }
        }
        else if (opt == "mf") //创建一个文件
        {
            string name, type;
            fin >> name >> type;
            if (!createNewFile(name, type))
            {
                fin.close();
                return 0;
            }
        }
        else if (opt == "cd") //切换目录
        {
            string name;
            fin >> name;
            if (!goToDir(name))
            {
                fin.close();
                return 0;
            }
        }
    }
    fin.close();
    return 1;
}
